package com.oros.db;
import java.io.*;
import java.util.*;

import com.vditl.core.DataOrgano;
public abstract class AEVaadTable implements VaadEngine, Serializable {
	private static final long serialVersionUID = 1L;
	protected AETableDefinition tableInfo; 
    private LinkedHashMap<String,String> tableProperties;
    private LinkedHashMap<String,LinkedHashMap<String,String>> fieldProperties;
	//this function can be overridden in the specific table implementation
	public String getVaadinSpecificTableInfo()
	    {
	    	return null;
	    }
   //this function can be overridden in the specific table implementation
   public String getVaadinSpecificFieldInfo(int colno)
	{
	    	return null;
	}
   private void init()
   {
	   tableProperties = new LinkedHashMap<String,String>();
	   fieldProperties = new LinkedHashMap<String,LinkedHashMap<String,String>>();
       addTablePropertyList(getVaadinSpecificTableInfo());
       if (tableInfo!=null && tableInfo.columnNames!=null)
       {
    	   int colno = tableInfo.columnNames.length;
    	   for(int i=0;i<colno;i++)
    	   {
    		   String description = getVaadinSpecificFieldInfo(colno);
    		   if (description!=null)
    		   {
    			   addFieldPropertyList(tableInfo.columnNames[i],description);
    		   }
    	   }
       }
   }
   public void addFieldPropertyList(String columnName,String description)
   {
	   if (tableProperties==null) init();
	   if (description==null) return;
	   description = description.trim();
	   int n=DataOrgano.GetSmartFieldQuantity(description, ',');
	   for(int i=0;i<n;i++)
	   {
             String s = DataOrgano.GetSmartFieldValue(description,',',i);	
             String key = DataOrgano.GetSmartFieldValue(s, ':', 0);
             String val = DataOrgano.GetSmartFieldValueRest(s, ':', 1);
             setFieldProperty(columnName,key,val);
	   }
   }
   public void addTablePropertyList(String description)
   {
	   if (tableProperties==null) init();
	   if (description==null) return;
	   description = description.trim();
	   int n=DataOrgano.GetSmartFieldQuantity(description, ',');
	   for(int i=0;i<n;i++)
	   {
             String s = DataOrgano.GetSmartFieldValue(description,',',i);	
             String key = DataOrgano.GetSmartFieldValue(s, ':', 0);
             String val = DataOrgano.GetSmartFieldValueRest(s, ':', 1);
             setTableProperty(key,val);
	   }
   }
   public String getTableProperty(String property)
   {
	   if (tableProperties==null) init();
	   if (property==null) return null;
	   return tableProperties.get(property.trim().toLowerCase());
   }
   private String refineValue(String value)
   {
	   if (value==null) return null;
	   value=value.trim();
	   if (value.startsWith("\"") && value.endsWith("\"")) value = value.substring(1, value.length()-1);
	   return value;
   }
   public void setTableProperty(String property,String value)
   {
	   if (property==null) return;
	   if (tableProperties==null) init();
	   if (value==null) 
		   {
		      tableProperties.remove(property.trim().toLowerCase());
		   }
	   else tableProperties.put(property.trim().toLowerCase(), refineValue(value));
   }
   public void setTableProperty(String property,String value,int beginIndex,int endIndex)
   {
	   value = value.substring(beginIndex, endIndex);
	   setTableProperty(property,value);
   }
   public void setFieldProperty(String columnName,String property,String value)
   {
	   if (columnName==null || property==null) return;
	   if (tableProperties==null) init();
	   columnName = columnName.trim().toLowerCase();
	   property = property.trim().toLowerCase();
	   LinkedHashMap<String,String> colmap = fieldProperties.get(columnName);
	   if (colmap==null)
	   {
		   colmap=new LinkedHashMap<String,String>();
		   fieldProperties.put(columnName, colmap);
	   }
	   if (value==null) colmap.remove(property);
	   else colmap.put(property, refineValue(value));
   }
   public String getFieldProperty(String columnName,String property)
   {
	   if (columnName==null || property==null) return null;
	   if (tableProperties==null) init();
	   columnName = columnName.trim().toLowerCase();
	   property = property.trim().toLowerCase();
	   LinkedHashMap<String,String> colmap = fieldProperties.get(columnName);
	   if (colmap==null)
	   {
		   colmap=new LinkedHashMap<String,String>();
		   fieldProperties.put(columnName, colmap);
	   }
	   return colmap.get(property);
   }
   public LinkedHashMap<String,String> getTablePropertyMap()
   {
	   if (tableProperties==null) init();
       return tableProperties;	   
   }
   public LinkedHashMap<String,String> getColumnPropertyMap(String columnName)
   {
	   if (columnName==null) return null;
	   columnName = columnName.trim().toLowerCase();
	   LinkedHashMap<String,String> colmap = fieldProperties.get(columnName);
	   if (colmap==null)
	   {
		   colmap=new LinkedHashMap<String,String>();
		   fieldProperties.put(columnName, colmap);
	   }
       return colmap;	   
   }
   public AETableDefinition getTableInfo() { return tableInfo;}
   
   public AETableContainer getContainer() throws Exception
   {
	   AETableContainer container = new AETableContainer(tableInfo,true,this);
	   return container;
   }
   public void validateTableAndFieldProperties(HashSet<String> tableDictionary,HashSet<String> fieldDictionary) throws Exception
   {
	   if (tableInfo==null) throw new Exception("tableInfo is not specified (null)");
	   String[] cols=tableInfo.columnNames;
	   if (cols==null || cols.length==0) throw new Exception("column names are not specified (null)");
	   int n=cols.length;
	   LinkedHashSet<String> columnDictionary = new LinkedHashSet<String>();
	   for(int i=0;i<n;i++) columnDictionary.add(cols[i].toLowerCase());
	   LinkedHashMap<String,String> tableProps = getTablePropertyMap();
	   for(String key:tableProps.keySet()) if (!tableDictionary.contains(key))
		   throw new Exception("Table property "+key+" is unknown");
	   for(String colname:fieldProperties.keySet())
	   {
		   if (!columnDictionary.contains(colname)) 
			   throw new Exception("Property column name "+colname+" is not present in table "+tableInfo.tableName);
		   LinkedHashMap<String,String> colmap = fieldProperties.get(colname);
		   for(String key:colmap.keySet())
		   {
			   if (!fieldDictionary.contains(key)) 
				   throw new Exception("Property "+key+" for column "+colname+" in table "+tableInfo.tableName+" is unknown");
		   }
	   }
	   
   }
   public String getFieldReferencedTable(int colno)
   {
   	   return null;
   }	
}
